import { ref, computed } from 'vue'

interface VirtualScrollOptions {
  itemHeight: number
  containerHeight: number
  buffer?: number
  threshold?: number
}

interface VirtualScrollItem {
  id: string | number
  [key: string]: any
}

export function useVirtualScroll<T extends VirtualScrollItem>(
  items: T[],
  options: VirtualScrollOptions
) {
  const { itemHeight, containerHeight, buffer = 5, threshold = 0.8 } = options
  
  const scrollTop = ref(0)
  const containerRef = ref<HTMLElement>()
  
  // 计算可见区域
  const visibleCount = Math.ceil(containerHeight / itemHeight)
  const totalHeight = computed(() => items.length * itemHeight)
  
  // 计算当前可见的项目范围
  const visibleRange = computed(() => {
    const start = Math.floor(scrollTop.value / itemHeight)
    const end = Math.min(start + visibleCount + buffer * 2, items.length)
    const actualStart = Math.max(0, start - buffer)
    
    return {
      start: actualStart,
      end,
      offsetY: actualStart * itemHeight
    }
  })
  
  // 获取可见的项目
  const visibleItems = computed(() => {
    const { start, end } = visibleRange.value
    return items.slice(start, end).map((item, index) => ({
      ...item,
      index: start + index,
      top: (start + index) * itemHeight
    }))
  })
  
  // 滚动事件处理
  const handleScroll = (event: Event) => {
    const target = event.target as HTMLElement
    scrollTop.value = target.scrollTop
  }
  
  // 滚动到指定项目
  const scrollToItem = (index: number) => {
    if (containerRef.value) {
      const targetScrollTop = index * itemHeight
      containerRef.value.scrollTop = targetScrollTop
      scrollTop.value = targetScrollTop
    }
  }
  
  // 滚动到顶部
  const scrollToTop = () => {
    scrollToItem(0)
  }
  
  // 滚动到底部
  const scrollToBottom = () => {
    scrollToItem(items.length - 1)
  }
  
  // 检查是否接近底部（用于无限滚动）
  const isNearBottom = computed(() => {
    const scrollBottom = scrollTop.value + containerHeight
    const totalScrollHeight = totalHeight.value
    return scrollBottom >= totalScrollHeight * threshold
  })
  
  return {
    containerRef,
    scrollTop,
    totalHeight,
    visibleItems,
    visibleRange,
    isNearBottom,
    handleScroll,
    scrollToItem,
    scrollToTop,
    scrollToBottom
  }
}